package com.cennavi.minenavidemo.presenter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;

import com.cennavi.minenavidemo.R;
import com.cennavi.minenavidemo.utils.Config;
import com.cennavi.minenavidemo.widget.MyMapView;
import com.minedata.minenavi.map.AirLineOverlay;
import com.minedata.minenavi.map.Circle;
import com.minedata.minenavi.map.CircleOptions;
import com.minedata.minenavi.map.ColorfulPolyline;
import com.minedata.minenavi.map.ColorfulPolylineOptions;
import com.minedata.minenavi.map.CompassOverlay;
import com.minedata.minenavi.map.DestinationLabel;
import com.minedata.minenavi.map.FavoritePoiLayer;
import com.minedata.minenavi.map.HaloCircleOverlay;
import com.minedata.minenavi.map.HaloRippleCircleOptions;
import com.minedata.minenavi.map.HeatMapLayer;
import com.minedata.minenavi.map.HeatMapLayerOptions;
import com.minedata.minenavi.map.Marker;
import com.minedata.minenavi.map.MarkerOptions;
import com.minedata.minenavi.map.MaskDrawer;
import com.minedata.minenavi.map.MineMap;
import com.minedata.minenavi.map.Model;
import com.minedata.minenavi.map.ModelOptions;
import com.minedata.minenavi.map.MultiPointOverlay;
import com.minedata.minenavi.map.MultiPointOverlayOptions;
import com.minedata.minenavi.map.MyLocationStyle;
import com.minedata.minenavi.map.NavigateArrow;
import com.minedata.minenavi.map.NavigateArrowOptions;
import com.minedata.minenavi.map.ODAirLineOptions;
import com.minedata.minenavi.map.ODLineOverlay;
import com.minedata.minenavi.map.Overlay;
import com.minedata.minenavi.map.PoiSearchResultLayer;
import com.minedata.minenavi.map.Polygon;
import com.minedata.minenavi.map.PolygonOptions;
import com.minedata.minenavi.map.Polyline;
import com.minedata.minenavi.map.PolylineOptions;
import com.minedata.minenavi.map.RippleCircleOverlay;
import com.minedata.minenavi.map.Route;
import com.minedata.minenavi.map.RouteOptions;
import com.minedata.minenavi.map.SuperclusterLayer;
import com.minedata.minenavi.map.SuperclusterOptions;
import com.minedata.minenavi.map.Texture;
import com.minedata.minenavi.mapdal.LatLng;
import com.minedata.minenavi.mapdal.NativeEnv;
import com.minedata.minenavi.mapdal.NcPoiFavoriteItem;
import com.minedata.minenavi.mapdal.NdsPoint;
import com.minedata.minenavi.mapdal.PoiItem;
import com.minedata.minenavi.mapdal.Tools;
import com.minedata.minenavi.navi.ArrowInfo;
import com.minedata.minenavi.navi.RouteBase;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.minedata.minenavi.map.PolylineOptions.DOTTEDLINE_TYPE_SQUARE;

public class MapPresenter {
    private static final String TAG = "MapPresenter";

    private Context mContext;
    private NaviPresenter mNaviPresenter;
    private MyMapView mMapView;
    private MineMap mMineMap;
    private MineMap mSmallMineMap;
    private MaskDrawer mSmallMapViewMaskDrawer;
    private AirLineOverlay mAirLineOverlay = null;
    private HaloCircleOverlay mHaloCircleOverlay = null;
    private MyLocationStyle mMyLocationStyle;
    private Circle mCircle;
    private ColorfulPolyline mColorfulPolyline = null;
    private Marker mMarker = null;
    private Marker mPoiMarker;
    private Polygon mPolygon1;
    private Polygon mPolygon2;
    private Polygon mPolygon3;
    private HeatMapLayer mHeatMapLayer;
    private MultiPointOverlay mMultiPointOverlay;
    private ODLineOverlay mODLineOverlay = null;
    private RippleCircleOverlay mRippleCircleOverlay = null;
    private SuperclusterLayer mSuperclusterLayer;
    private FavoritePoiLayer mFavoritePoiLayer;
    private Polyline mPolyline = null;
    private Model mModel;
    // 导航线
    private Route mRoute;
    // 小地图导航线
    private Route mSmallRoute;
    // 导航小车
    private Model mMapCar;
    // 导航箭头
    private NavigateArrow mNavigateArrow;
    // 小地图起点
    private MyLocationStyle mSmallMapStartPoint;
    // 小地图终点
    private MyLocationStyle mSmallMapEndPoint;
    private MyLocationStyle mSmallMapCar;
    private DestinationLabel mDestinationLabel;
    private CompassOverlay mNaviCompassOverlay;
    private PoiSearchResultLayer mPoiSearchResultLayer;//展示搜索结果图层
    private PoiItem mSelectedPoiItem;
    private float[] mScaleFactorSize = {1.1f, 1.3f, 1.5f, 1.7f, 1.9f};
    private int mTextSizeChangedIndex;
    private OnMapViewListener mOnMapViewListener;
    private Timer mTimer = null;
    private TimerTask mTimerTask = null;

    public interface OnMapViewListener {
        //搜索完成
        void onMapReady();

        void onswitchLocation(int imageLevel);
    }

    private MapPresenter() {
    }

    private static class SingletonHolder {
        public static final MapPresenter instance = new MapPresenter();
    }

    public static MapPresenter getInstance() {
        return SingletonHolder.instance;
    }

    public void setOnMapViewListener(OnMapViewListener listener) {
        mOnMapViewListener = listener;
    }

    public void init(Context context, MyMapView mapView) {
        mContext = context;
        mMapView = mapView;
        mNaviPresenter = NaviPresenter.getInstance();

        mMapView.addMapRenderCallback(mineMap -> {
            mMineMap = mineMap;
            mMineMap.setMinZoomLevel(0.0f);
            mMineMap.setMaxZoomLevel(17.0f);
            mOnMapViewListener.onMapReady();
        });
    }

    public void initPoiSearchResultLayer() {
        mPoiSearchResultLayer = new PoiSearchResultLayer(mMineMap);
        mPoiSearchResultLayer.addPoiClickListener(new PoiSearchResultLayer.PoiClickedListener() {
            @Override
            public void onPoiClicked(PoiItem poiItem) {
                if (mSelectedPoiItem == null) {
                    mPoiSearchResultLayer.setSelectedPoiItem(poiItem);
                    mSelectedPoiItem = poiItem;
                } else {
                    mPoiSearchResultLayer.unselectPoiItem();

                    if (poiItem.weakEquals(mSelectedPoiItem)) {
                        mSelectedPoiItem = null;
                    } else {
                        mPoiSearchResultLayer.setSelectedPoiItem(poiItem);
                        mSelectedPoiItem = poiItem;
                    }
                }
            }
        });
    }


    /**
     * 初始化小地图
     */
    public void initSmallMapView() {
        mSmallMineMap = mMapView.getSmallMineMap();

        if (mSmallMineMap == null) {
            return;
        }

        mSmallMineMap.setMinZoomLevel(0.0f);
        mSmallMineMap.setMaxZoomLevel(12.0f);
        Texture texture = new Texture("res/small_map_stencil.png");
        mSmallMapViewMaskDrawer = new MaskDrawer(texture, MaskDrawer.Method.fbo);
        mSmallMapViewMaskDrawer.setRect(mSmallMineMap.getViewport());
        mSmallMineMap.setDpiFactor((float) (NativeEnv.getDpi() * 1.2 / 160));
        mSmallMineMap.setMaskDrawer(mSmallMapViewMaskDrawer);
        mSmallMineMap.enableMaskDraw(true);
        mMapView.setSmallViewVisible(false);
    }

    public MineMap getMineMap() {
        return mMineMap;
    }

    public MineMap getSmallMineMap() {
        return mSmallMineMap;
    }

    public void showPoiSearchResultLayer(ArrayList<PoiItem> poiItems) {
        mPoiSearchResultLayer.syncPoiItems(poiItems);
    }

    public void setAutoZoomLevel() {
        float zoomLevel = mMineMap.getAutomaticZoomLevelForMineMap(0.2f);

        if (zoomLevel != -1) {
            mMineMap.setZoomLevel(zoomLevel);
        }
    }

    public MaskDrawer getSmallMapViewMaskDrawer() {
        return mSmallMapViewMaskDrawer;
    }

    public Rect getSmallMapViewRouteRect() {
        return mSmallRoute.getBoundingBox();
    }

    public void addAirLine() {
        ODAirLineOptions options = new ODAirLineOptions();

        //beijing->dalian
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(38.91459, 121.618622), Color.argb(255, 255, 255, 0)));
        //beijing->shanghai
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(31.40527, 121.48941), Color.argb(255, 255, 0, 0)));
        //beijing->xi,an
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(34.23053, 108.93425), Color.argb(255, 255, 0, 255)));
        //beijing->chengdu
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(30.65984, 104.10194), Color.argb(255, 0, 255, 255)));
        //beijing->huhehaote
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(40.80772, 111.62299), Color.argb(255, 0, 255, 0)));
        //beijing->changchu
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(43.83327, 125.28845), Color.argb(255, 0, 0, 255)));

        options.width(4.0f);

        mAirLineOverlay = mMineMap.addAirLineOverlay(options);
        startTimer();
    }

    public void addHaloCircle() {
        LatLng latLng = new LatLng(39.984066, 116.307734);

        HaloRippleCircleOptions options = new HaloRippleCircleOptions();
        HaloRippleCircleOptions.HaloRippleCircleItem item = new HaloRippleCircleOptions.HaloRippleCircleItem(latLng).color(Color.argb(50, 255, 0, 0));
        options.add(item);

        HaloRippleCircleOptions.HaloRippleCircleItem item1 = new HaloRippleCircleOptions.HaloRippleCircleItem(new LatLng(39.995059, 116.307771))
                .color(Color.argb(50, 255, 255, 0));
        options.add(item1);

        options.maxRadius(90.0f);
        mHaloCircleOverlay = mMineMap.addHaloCircleOverlay(options);

        startTimer();
    }

    public void addODLineOverlay() {
        ODAirLineOptions options = new ODAirLineOptions();

        //beijing->dalian
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(38.91459, 121.618622), Color.argb(255, 255, 255, 0)));
        //beijing->shanghai
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(31.40527, 121.48941), Color.argb(255, 255, 0, 0)));
        //beijing->xi,an
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(34.23053, 108.93425), Color.argb(255, 255, 0, 255)));
        //beijing->chengdu
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(30.65984, 104.10194), Color.argb(255, 0, 255, 255)));
        //beijing->huhehaote
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(40.80772, 111.62299), Color.argb(255, 0, 255, 0)));
        //beijing->changchu
        options.addItem(new ODAirLineOptions.ODAirLineItem(new LatLng(39.984066, 116.307734), new LatLng(43.83327, 125.28845), Color.argb(255, 0, 0, 255)));

        options.width(4.0f);

        mODLineOverlay = mMineMap.addODLineOverlay(options);
        startTimer();
    }

    public void addRippleCircle() {
        LatLng latLng = new LatLng(39.984066, 116.307734);

        HaloRippleCircleOptions options = new HaloRippleCircleOptions();
        HaloRippleCircleOptions.HaloRippleCircleItem item = new HaloRippleCircleOptions.HaloRippleCircleItem(latLng).color(Color.argb(50, 255, 0, 0));
        options.add(item);

        HaloRippleCircleOptions.HaloRippleCircleItem item1 = new HaloRippleCircleOptions.HaloRippleCircleItem(new LatLng(39.995059, 116.307771))
                .color(Color.argb(50, 255, 255, 0));
        options.add(item1);

        options.maxRadius(60.0f);
        mRippleCircleOverlay = mMineMap.addRippleCircleOverlay(options);
        startTimer();
    }

    public void stopTimer() {
        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }
        if (mTimerTask != null) {
            mTimerTask.cancel();
            mTimerTask = null;
        }
    }

    public void startTimer() {
        if (null == mTimer) {
            mTimer = new Timer();
        }
        if (null == mTimerTask) {
            mTimerTask = new TimerTask() {
                @Override
                public void run() {
                    if (mAirLineOverlay != null) {
                        mAirLineOverlay.moveSegIndex();
                    }

                    if (mHaloCircleOverlay != null) {
                        mHaloCircleOverlay.updateRadius();
                    }

                    if (mODLineOverlay != null) {
                        mODLineOverlay.moveSegIndex();
                    }

                    if (mRippleCircleOverlay != null) {
                        mRippleCircleOverlay.updateRadius();
                    }

                }
            };
            mTimer.schedule(mTimerTask, 0, 100);
        }
    }

    /**
     * 读取asset目录下文件。
     *
     * @return content
     */
    public static String readAssetFile(Context mContext, String file, String code) {
        int len = 0;
        byte[] buf = null;
        String result = "";
        try {
            InputStream in = mContext.getAssets().open(file);
            len = in.available();
            buf = new byte[len];
            in.read(buf, 0, len);

            result = new String(buf, code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    // 加载测试数据
    public static List<HeatMapLayerOptions.HeatMapItem> buildHeatmapDataSource(Context context, String path) {
        String s = readAssetFile(context, path, "UTF-8");
        String[] split = s.split("\n");
        List<HeatMapLayerOptions.HeatMapItem> items = new ArrayList<>();

        for (int i = 1; i < split.length; i++) {
            String[] point = split[i].split(",");
            HeatMapLayerOptions.HeatMapItem item = new HeatMapLayerOptions.HeatMapItem();
            item.setLatLng(Tools.pointToLatLng(new Point(Integer.parseInt(point[0]), Integer.parseInt(point[1]))));
            items.add(item);
        }

        return items;
    }

    public void addHeatmapLayer() {
        HeatMapLayerOptions options = new HeatMapLayerOptions();
        options.addAll(buildHeatmapDataSource(mContext, "navicore/other/merged1.cases.png"));
        mHeatMapLayer = mMineMap.addHeatMapLayer(options);
    }

    public HeatMapLayer getHeatmapLayer() {
        return mHeatMapLayer;
    }

    public void addMyLocationStyle() {
        // 定位蓝点，默认使用内置定位
        mMyLocationStyle = new MyLocationStyle();
        // 使用外部传入位置信息
        mMyLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
//            mMyLocationStyle.setPosition(point);
//            mMyLocationStyle.orientAngle(30.0f);
//            mMyLocationStyle.interval(2000);
        mMyLocationStyle.showMyLocation(true);
        mMyLocationStyle.setClickable(true);
        mMineMap.setMyLocationStyle(mMyLocationStyle);
    }

    MineMap.OnMarkerDragListener markerDragListener = new MineMap.OnMarkerDragListener() {
        @Override
        public void onMarkerDragStart(Marker marker) {
            LatLng latLng = marker.getOptions().getPosition();
        }

        @Override
        public void onMarkerDragEnd(Marker marker) {
            LatLng latLng = marker.getOptions().getPosition();
        }

        @Override
        public void onMarkerDragDrag(Marker marker) {
            LatLng latLng = marker.getOptions().getPosition();
        }
    };

    public void switchLocation(){
        //定位按钮点击时切换定位按钮背景，定位方式，移动到定位位置
        if (mMyLocationStyle != null) {
            if (mMyLocationStyle.getMyLocationType() != MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) {
                mMyLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
                mMyLocationStyle.showMyLocation(true);
                mOnMapViewListener.onswitchLocation(1);
            } else {
                mMyLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
                mMyLocationStyle.showMyLocation(false);
                mOnMapViewListener.onswitchLocation(0);
            }
        } else {
            mMyLocationStyle = new MyLocationStyle();
            mMyLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
            mMineMap.setMyLocationStyle(mMyLocationStyle);
            mMyLocationStyle.showMyLocation(true);
            mOnMapViewListener.onswitchLocation(1);
        }
    }

    public void addMarker() {
        Bitmap icon = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.hotel);

        LatLng latLng = new LatLng(41.834347, 123.548782);
        mMarker = mMineMap.addMarker(new MarkerOptions().zLevel(7).position(latLng).bitmap(icon)
                .setInfoWindowOffset(0.5f, 0.0f).title("你好").snippet("DefaultMarker")
                .titleColor(Color.argb(255, 255, 0, 255))
                .snippetColor(Color.argb(255, 255, 255, 0)).infoWindowEnable(true));
//                marker = mMineMap.addMarker(new MarkerOptions().zLevel(7).position(latLng).iconId(1415)
//                        .setInfoWindowOffset(0.5f, 0.0f).title("你好").snippet("DefaultMarker")
//                        .titleColor(Color.argb(255, 255, 0, 255))
//                        .snippetColor(Color.argb(255, 255, 255, 0)).infoWindowEnable(true));
        mMarker.setDraggable(true);
        mMineMap.setOnMarkerDragListener(markerDragListener);
    }

    public void addPoiMarker(LatLng latLng) {
        mPoiMarker = mMineMap.addMarker(new MarkerOptions().zLevel(7).position(latLng).iconId(1415).infoWindowEnable(false));
    }

    public void addPoiPolyline(List<LatLng> latLngs) {
        PolylineOptions options = new PolylineOptions().
                addAll(latLngs).width(10).color(Color.argb(255, 255, 0, 255))
                .outlineColor(Color.argb(255, 255, 0, 255)).zLevel(3).setDottedLineType(DOTTEDLINE_TYPE_SQUARE);

        mPolyline = mMineMap.addPolyline(options);
    }

    public void addCircle() {
        LatLng latLng = new LatLng(39.984059, 116.307771);

        CircleOptions options = new CircleOptions().
                center(latLng).
                radius(1000).
                fillColor(Color.argb(50, 255, 0, 0)).
                strokeColor(Color.argb(50, 0, 0, 255)).
                strokeWidth(15);

        mCircle = mMineMap.addCircle(options);
    }

    /**
     * 生成一个长方形的四个坐标点
     */
    private List<LatLng> createRectangle(LatLng center, double halfWidth,
                                         double halfHeight) {
        List<LatLng> latLngs = new ArrayList<LatLng>();
        latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude - halfWidth));
        latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude + halfWidth));
        latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude + halfWidth));
        latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));
        return latLngs;
    }

    public void addPolygon() {
        mPolygon1 = mMineMap.addPolygon(new PolygonOptions()
                .addAll(createRectangle(Config.NIAOCHAO, 1, 1))
                .fillColor(Color.LTGRAY).strokeColor(Color.RED).strokeWidth(1));

        PolygonOptions options = new PolygonOptions();
        int numPoints = 400;
        float semiHorizontalAxis = 5f;
        float semiVerticalAxis = 2.5f;
        double phase = 2 * Math.PI / numPoints;
        for (int i = 0; i <= numPoints; i++) {
            options.add(new LatLng(Config.NIAOCHAO.latitude
                    + semiVerticalAxis * Math.sin(i * phase),
                    Config.NIAOCHAO.longitude + semiHorizontalAxis
                            * Math.cos(i * phase)));
        }
        // 绘制一个椭圆
        mPolygon2 = mMineMap.addPolygon(options.strokeWidth(25)
                .strokeColor(Color.argb(50, 0, 255, 255))
                .fillColor(Color.argb(50, 0, 255, 255)));

        // 定义多边形的5个点点坐标
        LatLng latLng1 = new LatLng(42.742467, 79.842785);
        LatLng latLng2 = new LatLng(43.893433, 98.124035);
        LatLng latLng3 = new LatLng(33.058738, 101.463879);
        LatLng latLng4 = new LatLng(25.873426, 95.838879);
        LatLng latLng5 = new LatLng(30.8214661, 78.788097);

        // 声明 多边形参数对象
        PolygonOptions polygonOptions = new PolygonOptions();
        // 添加 多边形的每个顶点（顺序添加）
        polygonOptions.add(latLng1, latLng2, latLng3, latLng4, latLng5);
        polygonOptions.strokeWidth(15) // 多边形的边框
                .strokeColor(Color.argb(50, 255, 0, 255)) // 边框颜色
                .fillColor(Color.argb(1, 255, 0, 255));   // 多边形的填充色

        mPolygon3 = mMineMap.addPolygon(polygonOptions);
    }

    public void addPolyline(List<LatLng> latLngs) {
        PolylineOptions options = new PolylineOptions().
                addAll(latLngs).width(10).color(Color.argb(255, 255, 0, 255))
                .outlineColor(Color.argb(255, 255, 0, 255)).zLevel(3);

        mPolyline = mMineMap.addPolyline(options);
    }

    public void addPolyline() {
        List<LatLng> latLngs = new ArrayList<>();
        latLngs.add(new LatLng(39.999391, 116.135972));
        latLngs.add(new LatLng(39.999391, 116.257694));
        latLngs.add(new LatLng(39.899391, 116.257694));
        latLngs.add(new LatLng(39.899391, 116.357694));

        PolylineOptions options = new PolylineOptions().
                addAll(latLngs).width(10).color(Color.argb(255, 255, 0, 255))
                .outlineColor(Color.argb(255, 255, 0, 255)).zLevel(3);

        mPolyline = mMineMap.addPolyline(options);
    }

    public void addModel() {
        ModelOptions options = new ModelOptions()
                .objFile("res/3d_car.obj")
                .position(new LatLng(41.834347, 123.548782))
                .layer(Overlay.Layer.aboveMarker)
                .heading(0)
                .keepScaleSize(8.0f)
                .scaleFactor(0.15f)
                .visible(true);

        mModel = mMineMap.addModel(options);
    }

    // 加载测试数据
    public static List<SuperclusterOptions.SuperclusterItem> buildClusterDataSource(Context context, String path) {
        String s = readAssetFile(context, path, "UTF-8");
        String[] split = s.split("\r\n");

        if (split.length == 1) {
            split = s.split("\n");
        }

        List<SuperclusterOptions.SuperclusterItem> items = new ArrayList<>();

        for (int i = 1; i < split.length; i++) {
            String[] point = split[i].split(",");
            SuperclusterOptions.SuperclusterItem item = new SuperclusterOptions.SuperclusterItem();
            item.setLatLng(Tools.pointToLatLng(new Point(Integer.parseInt(point[0]), Integer.parseInt(point[1]))));
            items.add(item);
        }

        return items;
    }

    public void addSupercluster() {
        SuperclusterOptions options = new SuperclusterOptions();
        options.addAll(buildClusterDataSource(mContext, "navicore/other/merged1.cases.png"));
        mSuperclusterLayer = mMineMap.addSuperclusterLayer(options);
    }

    // 加载测试数据
    public static List<MultiPointOverlayOptions.MultiPointItem> buildMultiPointDataSource(Context context, String path) {
        String s = readAssetFile(context, path, "UTF-8");
        String[] split = s.split("\r\n");

        if (split.length == 1) {
            split = s.split("\n");
        }

        List<MultiPointOverlayOptions.MultiPointItem> items = new ArrayList<>();

        for (int i = 1; i < split.length; i++) {
            String[] point = split[i].split(",");
            MultiPointOverlayOptions.MultiPointItem item = new MultiPointOverlayOptions.MultiPointItem();
            item.latLng(Tools.pointToLatLng(new Point(Integer.parseInt(point[0]), Integer.parseInt(point[1]))));
            items.add(item);
        }

        return items;
    }

    public void addColorfulPolyline() {
        List<LatLng> latLngs = new ArrayList<>();
        latLngs.add(new LatLng(39.999391, 116.135972));
        latLngs.add(new LatLng(39.999391, 116.257694));
        latLngs.add(new LatLng(39.899391, 116.257694));
        latLngs.add(new LatLng(39.899391, 116.357694));

        byte[] segColorIndices = new byte[4];
        segColorIndices[0] = 0;
        segColorIndices[1] = 1;
        segColorIndices[2] = 2;
        segColorIndices[3] = 3;

        int[] pallettes = new int[4];
        pallettes[0] = Color.RED;
        pallettes[1] = Color.GREEN;
        pallettes[2] = Color.BLUE;
        pallettes[3] = Color.BLUE;

        ColorfulPolylineOptions options = new ColorfulPolylineOptions(segColorIndices, pallettes, ColorfulPolylineOptions.ColorMergeMode.noMerge);
        options.setPoints(latLngs);
        options.width(20);
        options.zLevel(3);
        options.outlineColor(Color.argb(255, 255, 0, 255));

        mColorfulPolyline = mMineMap.addColorfulPolyline(options);
    }

    public void addMultiPointOverlay() {
        MultiPointOverlayOptions options = new MultiPointOverlayOptions();
        options.addAll(buildMultiPointDataSource(mContext, "navicore/other/merged1.cases.png"));
        mMultiPointOverlay = mMineMap.addMultiPointOverlay(options);
    }

    public void addFavoritePoiLayer() {
        mFavoritePoiLayer = new FavoritePoiLayer(mMineMap);
        mFavoritePoiLayer.addListener(new FavoritePoiLayer.Listener() {
            @Override
            public void onHomeClicked(NcPoiFavoriteItem item) {
            }

            @Override
            public void onCompanyClicked(NcPoiFavoriteItem item) {
            }

            @Override
            public void onFavPoiClicked(NcPoiFavoriteItem item) {
            }
        });
    }

    public void showFavoritePoiLayer(List<NcPoiFavoriteItem> items) {
        mFavoritePoiLayer.syncItems(items);
    }

    /**
     * 添加导航线
     */
    public void drawRoute(RouteBase routeBase) {
        RouteOptions options = new RouteOptions()
                .routeBase(routeBase)
                .colorType(Route.RouteColorType.enrouteTi)
                .styleClass("DEFAULT");

        mRoute = mMineMap.addRoute(options);
        mSmallRoute = mSmallMineMap.addRoute(options);
        mSmallRoute.setZLevel(1);
        setRouteOverlayStyle(mRoute, false);
        setRouteOverlayStyle(mSmallRoute, true);
    }

    public void drawNavigateArrow(ArrowInfo arrowInfo) {
        NavigateArrowOptions options = new NavigateArrowOptions(arrowInfo);
        options.zLevel(10);
        options.enableBorder(true);
        options.layer(Overlay.Layer.aboveBase);
        options.width(15.0f);
        options.height(18.0f);
        options.topColor(0xffecfffd);
        options.borderWidth(6.0f);
        options.borderColor(0xff367973);
        options.sideColor(0xff61b5ae);

        mNavigateArrow = mMineMap.addNavigateArrow(options);
    }

    public void setRouteOverlayStyle(Route route, boolean isSmallMapRoute) {
        String routeStyle = "DEFAULT";

        if (isSmallMapRoute) {
            routeStyle += ",small-map";
        }
        route.selectStyleClass(routeStyle);
    }

    /**
     * 添加小地图的起终点
     */
    public void drawStartAndEndMyLocationStyle(Point startPoint, Point endPoint) {
        if (mSmallMineMap == null) {
            return;
        }
        if (mSmallMapStartPoint == null) {
            mSmallMapStartPoint = new MyLocationStyle("res/icons/startPointInSmallMap.png", true);
            mSmallMapStartPoint.myLocationType(MyLocationStyle.LOCATION_TYPE_EXTERNAL);
            float scaleFactor1 =
                    (float) Math.round((10 * NativeEnv.getDpi() * 4) * 10 / (160 * 36 * 3)) / 10;
            mSmallMapStartPoint.scaleFactor(scaleFactor1);
            mSmallMapStartPoint.anchor(0.5f, 0.5f);
            mSmallMapStartPoint.setPosition(startPoint);
            mSmallMineMap.setMyLocationStyle(mSmallMapStartPoint);

            mSmallMapEndPoint = new MyLocationStyle("res/icons/endPointInSmallMap.png", true);
            mSmallMapEndPoint.myLocationType(MyLocationStyle.LOCATION_TYPE_EXTERNAL);
            float scaleFactor2 =
                    (float) Math.round((10 * NativeEnv.getDpi() * 4) * 10 / (160 * 36 * 3)) / 10;
            mSmallMapEndPoint.scaleFactor(scaleFactor2);
            mSmallMapEndPoint.anchor(0.5f, 0.5f);
            mSmallMapEndPoint.setPosition(endPoint);
            mSmallMineMap.setMyLocationStyle(mSmallMapEndPoint);
        }
    }

    /**
     * 添加导航小车
     */
    public void drawNavingCar(Point point) {
        if (mSmallMineMap == null || mMineMap == null) {
            return;
        }

        if (mMapCar == null) {
            ModelOptions modelOptions = new ModelOptions()
                    // 模型文件相对路径
                    .objFile("res/3d_car.obj")
                    // 位置
                    .position(Tools.pointToLatLng(point))
                    // 图层布局类型
                    .layer(Overlay.Layer.aboveMarker)
                    // 方向角
                    .heading(0)
                    // 保持尺寸的比例尺
                    .keepScaleSize(8.0f)
                    // 缩放因子
                    .scaleFactor(0.15f)
                    // 可见性
                    .visible(true);

            mMapCar = mMineMap.addModel(modelOptions);
        }

        if (mSmallMapCar == null) {
            mSmallMapCar = new MyLocationStyle("res/icons/carIconInSmallMap.png", true);
            mSmallMapCar.myLocationType(MyLocationStyle.LOCATION_TYPE_EXTERNAL);
            float scaleFactor = (float) Math.round((10 * NativeEnv.getDpi() * 2) * 10 / (160 * 48)) / 10;
            mSmallMapCar.scaleFactor(scaleFactor);
            mSmallMapCar.anchor(0.5f, 0.5f);
            mSmallMapCar.setPosition(point);
            mSmallMineMap.setMyLocationStyle(mSmallMapCar);
        }
    }

    public void showDestinationLabel(RouteBase routeBase) {
        if (mDestinationLabel == null) {
            mDestinationLabel = new DestinationLabel(mMineMap);
        }
        mDestinationLabel.setRouteBase(routeBase);
        mDestinationLabel.setArrivalTextSize(12);
        mDestinationLabel.setPlaceNameTextSize(15);
        mDestinationLabel.setArrivalLineHeight(0.9f);
        mDestinationLabel.setPlaceNameLineHeight(0.8f);
        if (mNaviPresenter.isInNavigation()) {
            mDestinationLabel.setShowArrivalTime(false);
        } else {
            mDestinationLabel.setShowArrivalTime(true);
        }
    }

    /**
     * 车标东南西北控件
     */
    private void createCompassOverlay() {
        WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getMetrics(dm);
        // 应用程序根目录，企服用户应该保证此目录可读写，一般为sd卡上的mapbar/app目录，其他用户可根据需要自己设置
        // 设备dpi，和地图显示相关
        int dpi = dm.densityDpi;

        float scaleFactor = (float) Math.round((13 * dpi * 0.85 * 9) * 10 / (160 * 300)) / 10;
        mNaviCompassOverlay = new CompassOverlay("map3d/compass", 105);
        mNaviCompassOverlay.setScaleFactor(scaleFactor * mScaleFactorSize[mTextSizeChangedIndex]);
        mMineMap.addOverlay(mNaviCompassOverlay);
    }

    /**
     * 刷新导航中的自车位置
     */
    public void showNavingCarPosition(NdsPoint ndsPoint, float heading) {
        synchronized (NativeEnv.SyncObject) {
            if (ndsPoint == null) {
                return;
            }

            if (mNaviCompassOverlay == null) {
                createCompassOverlay();
            }

            mMapCar.setPositionNds(Tools.ndsPointToLatLng(ndsPoint));
            mMapCar.setHeading(heading);

            //刷新小地图自车位置
            if (mSmallMapCar != null) {
                mSmallMapCar.orientAngle(heading);
                mSmallMapCar.setPositionNds(Tools.ndsPointToLatLng(ndsPoint));
            }

            if (mNaviCompassOverlay != null) {
                mNaviCompassOverlay.setPositionNds(ndsPoint);
            }
        }
    }

    public void deleteAirLine() {
        if (mAirLineOverlay != null) {
            mMineMap.removeOverlay(mAirLineOverlay);
            mAirLineOverlay = null;
            stopTimer();
        }
    }

    public void deleteODLine() {
        if (mODLineOverlay != null) {
            mMineMap.removeOverlay(mODLineOverlay);
            mODLineOverlay = null;
            stopTimer();
        }
    }

    public void deleteHaloCircle() {
        if (mHaloCircleOverlay != null) {
            mMineMap.removeOverlay(mHaloCircleOverlay);
            mHaloCircleOverlay = null;
            stopTimer();
        }
    }

    public void deleteRippleCircle() {
        if (mRippleCircleOverlay != null) {
            mMineMap.removeOverlay(mRippleCircleOverlay);
            mRippleCircleOverlay = null;
            stopTimer();
        }
    }

    public void deleteMyLocationStyle() {
        if (mMyLocationStyle != null) {
            mMineMap.removeOverlay(mMyLocationStyle);
            mMyLocationStyle = null;
        }
    }

    public void deleteMarker() {
        if (mMarker != null) {
            mMineMap.removeMarker(mMarker);
            mMarker = null;
        }
    }

    public void deleteCircle() {
        if (mCircle != null) {
            mMineMap.removeOverlay(mCircle);
            mCircle = null;
        }
    }

    public void deletePolyline() {
        if (mPolyline != null) {
            mMineMap.removeOverlay(mPolyline);
            mPolyline = null;
        }
    }

    public void deletePolygon() {
        if (mPolygon1 != null) {
            mMineMap.removeOverlay(mPolygon1);
            mPolygon1 = null;
        }

        if (mPolygon2 != null) {
            mMineMap.removeOverlay(mPolygon2);
            mPolygon2 = null;
        }

        if (mPolygon3 != null) {
            mMineMap.removeOverlay(mPolygon3);
            mPolygon3 = null;
        }
    }

    public void deleteColorfulPolyline() {
        if (mColorfulPolyline != null) {
            mMineMap.removeOverlay(mColorfulPolyline);
            mColorfulPolyline = null;
        }
    }

    public void deleteModel() {
        if (mModel != null) {
            mMineMap.removeOverlay(mModel);
            mModel = null;
        }
    }

    public void deleteMultiPointOverlay() {
        if (mMultiPointOverlay != null) {
            mMultiPointOverlay.release();
            mMultiPointOverlay = null;
        }
    }

    public void deleteSupercluster() {
        if (mSuperclusterLayer != null) {
            mSuperclusterLayer.release();
            mSuperclusterLayer = null;
        }
    }

    public void deleteHeatMapLayer() {
        if (mHeatMapLayer != null) {
            mHeatMapLayer.release();
            mHeatMapLayer = null;
        }
    }

    /**
     * 移除导航小车
     */
    public void deleteNavingCar() {
        if (mMineMap != null && mMapCar != null) {
            mMineMap.removeOverlay(mMapCar);
            mMapCar.release();
            mMapCar = null;
        }

        if (mSmallMineMap != null && mSmallMapCar != null) {
            mSmallMineMap.removeOverlay(mSmallMapCar);
            mSmallMapCar.release();
            mSmallMapCar = null;
        }
    }

    /**
     * 移除藏当前的指南针overlay
     */
    public void deleteNaviCompassOverlay() {
        if (mNaviCompassOverlay != null) {
            mMineMap.removeOverlay(mNaviCompassOverlay);
            mNaviCompassOverlay = null;
        }
    }

    /**
     * 移除路线上的NavigateArrow
     */
    public void deleteNavigateArrow() {
        if (mNavigateArrow != null) {
            mMineMap.removeOverlay(mNavigateArrow);
            mNavigateArrow.release();
            mNavigateArrow = null;
        }
    }

    public void deleteRoute() {
        if (mRoute != null) {
            mMineMap.removeOverlay(mRoute);
            mRoute = null;
        }

        if (mSmallRoute != null) {
            mSmallMineMap.removeOverlay(mSmallRoute);
            mSmallRoute = null;
        }
    }

    public void deletePoiSearchResultLayer() {
        mPoiSearchResultLayer.clearAllPois();
    }

    public void deletePoiMarker() {
        if (mPoiMarker != null) {
            mMineMap.removeMarker(mPoiMarker);
            mPoiMarker = null;
        }
    }

    public void removeAllOverlays() {
        mMineMap.removeAllMarkers();
        mMineMap.removeAllOverlays();
        deletePoiSearchResultLayer();
        mSmallMineMap.removeAllMarkers();
        mSmallMineMap.removeAllOverlays();
        showDestinationLabel(null);

        mRoute = null;
        mMapCar = null;
        mSmallMapStartPoint = null;
        mSmallMapEndPoint = null;
        mSmallRoute = null;
        mSmallMapCar = null;
        mDestinationLabel = null;
    }

    public void switch2D() {
        //切换为2D平面图
        mMineMap.setElevation(90);
        mMineMap.setStyleClass("DEFAULT");
        mMineMap.enableSatelliteLayer(false);
    }

    public void switchSatelliteLayer() {
        //切换为卫星图
        mMineMap.setElevation(90);
        mMineMap.setSatelliteImageType(MineMap.SatelliteImageSource.bing);
        mMineMap.setStyleClass("SATELLITE");
        mMineMap.enableSatelliteLayer(true);
    }

    public void switch3D() {
        //切换为3D俯视图
        mMineMap.setElevation(0);
        mMineMap.setStyleClass("DEFAULT");
        mMineMap.enableSatelliteLayer(false);
    }

    int count = 0;

    public void mapbound() {
        if (count == 0) {
            Rect rect = mMineMap.getBoundArea();
            Rect rect1 = new Rect(rect.left / 2, rect.top / 2, rect.right / 2, rect.bottom / 2);
            mMineMap.setBoundArea(rect1);
            count++;
        }
    }
}
